package api

import (
	"openapi.itspire.cn/common/dict"
	"openapi.itspire.cn/common/global"
	"openapi.itspire.cn/common/throw"
	"openapi.itspire.cn/database"
	"openapi.itspire.cn/model"
	"openapi.itspire.cn/utils"
	"github.com/gin-gonic/gin"
	"strconv"
)

func ArticleList(c *gin.Context) {
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	size := global.PageSize

	list := make([]*model.ArticleList, 0)
	total := 0

	var article model.Article
	query := database.Ins.
		Model(&article).
		Where("status = ? AND delete_time = ?", dict.StatusOn, dict.DeleteNot)
	if err := query.Count(&total).Error; err != nil {
		panic(err)
	}

	if total > 0 {
		query = database.Ins.
			Table(article.GetTableName()+" a").
			Select("a.id,a.title,a.category_id,a.introduction,a.comment_num,a.reading_num,a.is_top,a.publish_time,b.category_name").
			Joins("left join "+model.Category{}.GetTableName()+" b on a.category_id = b.id").
			Where("a.status = ? AND a.delete_time = ?", dict.StatusOn, dict.DeleteNot).
			Order("a.is_top desc, a.publish_time desc").
			Limit(size).
			Offset((page - 1) * size)
		if err := query.Scan(&list).Error; err != nil {
			panic(err)
		}
		for _, v := range list {
			v.FormatTime = utils.FormatTime(v.PublishTime)
		}
	}

	maps := make(map[string]interface{})
	maps["pagination"] = map[string]int{"page": page, "size": size, "total": total}
	maps["list"] = list

	utils.Success(c, maps)
}

func ArticleInfo(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10 ,64)

	var article model.Article
	query := database.Ins.
		Table(article.GetTableName()+" a").
		Select("a.id,a.title,a.content,a.comment_num,a.reading_num,a.publish_time,b.category_name").
		Joins("left join "+model.Category{}.GetTableName()+" b on a.category_id = b.id").
		Where("a.id = ? AND a.status = ? AND a.delete_time = ?", id, dict.StatusOn, dict.DeleteNot)
	res := query.Scan(&article)
	if res.RecordNotFound() == true {
		throw.NotFound(c, "记录不存在")
		return
	}
	if err := query.Error; err != nil {
		panic(err)
	}

	// 文章标签
	label := make([]model.ArticleLabel, 0)
	queryLabel := database.Ins.
		Table(model.ArticleLabel{}.GetTableName()+" a").
		Select("a.label_id,b.category_name as label_name").
		Joins("left join "+model.Category{}.GetTableName()+" b on a.label_id = b.id").
		Where("a.article_id = ? AND b.status = ? AND b.delete_time = ?", id, dict.StatusOn, dict.DeleteNot)
	if err := queryLabel.Scan(&label).Error; err != nil {
		panic(err)
	}

	// 上一篇下一篇
	articleId := make([]model.ArticleId, 2)
	lastArticle := make(map[string]interface{})
	nextArticle := make(map[string]interface{})
	res2 := database.Ins.Raw("(select id,title from it_article where id < ? and status = ? and delete_time = ? order by id desc limit 1) " +
		"union all " +
		"(select id,title from it_article where id > ? and status = ? and delete_time = ? limit 1)", id, dict.StatusOn, dict.DeleteNot, id, dict.StatusOn, dict.DeleteNot).
		Scan(&articleId)
	if res2.RecordNotFound() == false {
		for _, v := range articleId {
			maps := utils.StructToMap(v, "json")
			value := maps["id"].(uint64)
			if value < id {
				lastArticle = maps
			} else {
				nextArticle = maps
			}
		}
	}

	article.LabelList = label
	article.LastArticle = lastArticle
	article.NextArticle = nextArticle

	utils.Success(c, article)
}

func ArticleHot(c *gin.Context) {
	list := make([]*model.ArticleHot, 0)
	size := global.ArticleHot

	var article model.Article
	query := database.Ins.
		Table(article.GetTableName()).
		Select("id,title,reading_num").
		Where("status = ? AND delete_time = ?", dict.StatusOn, dict.DeleteNot).
		Order("reading_num desc, publish_time desc").
		Limit(size)
	if err := query.Scan(&list).Error; err != nil {
		throw.ServerError(c, err.Error())
		return
	}

	utils.Success(c, list)
}

func ArticleNew(c *gin.Context) {
	list := make([]*model.ArticleNew, 0)
	size := global.ArticleNew

	var article model.Article
	query := database.Ins.
		Table(article.GetTableName()).
		Select("id,title,publish_time").
		Where("status = ? AND delete_time = ?", dict.StatusOn, dict.DeleteNot).
		Order("publish_time desc").
		Limit(size)
	if err := query.Scan(&list).Error; err != nil {
		throw.ServerError(c, err.Error())
		return
	}

	utils.Success(c, list)
}

func ArticleSearch(c *gin.Context) {
	var article model.Article
	list := make([]*model.ArticleSearch, 0)
	query := database.Ins.
		Table(article.GetTableName()).
		Select("id,title").
		Where("status = ? AND delete_time = ?", dict.StatusOn, dict.DeleteNot).
		Order("id desc")
	if err := query.Scan(&list).Error; err != nil {
		throw.ServerError(c, err.Error())
		return
	}

	utils.Success(c, list)
}